package gamelogic

import (
	"server_cluster/common/mysock"
	"server_cluster/common/tools"
	"strconv"
	"strings"
	"time"

	"server_cluster/common/config"
	"server_cluster/common/gdconf"
	"server_cluster/common/logger"
	"server_cluster/common/protoc/pb"
	"server_cluster/logic/sharemem"
)

type TaskPointReward struct {
	Point  int32
	Reward int32
}

func ParseTaskPointRewardConfig(str string) []*TaskPointReward {
	ret := make([]*TaskPointReward, 0)
	split1 := strings.Split(str, ";")
	for _, s := range split1 {
		split2 := strings.Split(s, "|")
		if len(split2) != 2 {
			logger.Error("任务活跃点配置解析失败 %v", str)
			return nil
		}
		point, err := strconv.Atoi(split2[0])
		if err != nil {
			logger.Error("任务活跃点配置解析失败 %v", str)
			return nil
		}
		reward, err := strconv.Atoi(split2[1])
		if err != nil {
			logger.Error("任务活跃点配置解析失败 %v", str)
			return nil
		}
		ret = append(ret, &TaskPointReward{
			Point:  int32(point),
			Reward: int32(reward),
		})
	}
	return ret
}

func signInRewardDaily(user *sharemem.User, req *pb.CS_SignInRewardTakeReq) (int32, map[int32]int32) {
	signInReward := user.GetDailySignInReward(req.ActivityId, req.RewardDay)
	if signInReward == nil {
		logger.Error("每日签到奖励天数不存在 %v", req.RewardDay)
		return config.OBJECT_NOT_FOUND, nil
	}
	if signInReward.RewardTake {
		logger.Error("每日签到奖励已领取 %v", req.RewardDay)
		return config.SERVER_ERROR, nil
	}
	signInReward.RewardTake = true
	activityConfig := gdconf.GetSignInActivityConfig(req.ActivityId)
	if activityConfig == nil {
		return config.CONFIG_NOT_FOUND, nil
	}
	for _, signInDailyReward := range activityConfig.DailyReward {
		if signInDailyReward.RewardDay == signInReward.RewardDay {
			ret, itemMap, _ := RewardItem(signInDailyReward.RewardId, nil, user)
			if ret != config.OK {
				logger.Error("发奖失败 %v %v", signInDailyReward.RewardId, ret)
			}
			return config.OK, itemMap
		}
	}
	return config.OK, nil
}

func signInRewardTotal(user *sharemem.User, req *pb.CS_SignInRewardTakeReq) (int32, map[int32]int32) {
	signInReward := user.GetTotalSignInReward(req.ActivityId, req.RewardDay)
	if signInReward == nil {
		logger.Error("累计签到奖励天数不存在 %v", req.RewardDay)
		return config.OBJECT_NOT_FOUND, nil
	}
	if signInReward.RewardTake {
		logger.Error("累计签到奖励已领取 %v", req.RewardDay)
		return config.SERVER_ERROR, nil
	}
	signInReward.RewardTake = true
	activityConfig := gdconf.GetSignInActivityConfig(req.ActivityId)
	if activityConfig == nil {
		return config.CONFIG_NOT_FOUND, nil
	}
	for _, signInTotalReward := range activityConfig.TotalReward {
		if signInTotalReward.RewardDay == signInReward.RewardDay {
			ret, itemMap, _ := RewardItem(signInTotalReward.RewardId, nil, user)
			if ret != config.OK {
				logger.Error("发奖失败 %v %v", signInTotalReward.RewardId, ret)
			}
			return config.OK, itemMap
		}
	}
	return config.OK, nil
}

func signInRewardDailyRoutine(user *sharemem.User, req *pb.CS_SignInRewardTakeReq) (int32, map[int32]int32) {
	signIn := user.GetSignInfoById(req.ActivityId)
	if signIn == nil {
		return config.OBJECT_NOT_FOUND, nil
	}
	if signIn.SignInDailyRoutineRewardTake {
		logger.Error("每日常规奖励已领取")
		return config.SERVER_ERROR, nil
	}
	signIn.SignInDailyRoutineRewardTake = true
	activityConfig := gdconf.GetSignInActivityConfig(req.ActivityId)
	if activityConfig == nil {
		return config.CONFIG_NOT_FOUND, nil
	}
	ret, itemMap, _ := RewardItem(activityConfig.DailyRoutineRewardId, nil, user)
	if ret != config.OK {
		logger.Error("发奖失败 %v %v", activityConfig.DailyRoutineRewardId, ret)
	}
	return config.OK, itemMap
}

func zpTaskRewardTake(user *sharemem.User, zpTask *sharemem.Task, zpActivityConfig *gdconf.ZpActivityConfig) (bool, map[int32]int32) {
	if pb.TaskState(zpTask.State) != pb.TaskState_TASK_STATE_FINISH {
		logger.Error("转盘活动任务状态不是已完成 %v", zpTask.State)
		return false, nil
	}
	zpTask.State = int8(pb.TaskState_TASK_STATE_ALREADY_REWARD)
	zpTaskConfig := zpActivityConfig.GetZpTask(zpTask.TaskId)
	if zpTaskConfig == nil {
		logger.Error("zp task config is nil, TaskId: %v", zpTask.TaskId)
		return false, nil
	}
	var rewardCount int32 = 1
	if zpTaskConfig.RefreshType == gdconf.ZpTaskRefreshTypeResetState {
		zpTask.State = int8(pb.TaskState_TASK_STATE_UNFINISH)
		rewardCount = zpTask.FinishCount / (zpTaskConfig.FinishCount)
		zpTask.FinishCount %= zpTaskConfig.FinishCount
		zpTask.RewardTakeCount += rewardCount
	}
	itemMap := make(map[int32]int32)
	for i := 0; i < int(zpTaskConfig.RewardCount*rewardCount); i++ {
		ret, itemOnceMap, _ := RewardItem(zpTaskConfig.RewardId, nil, user)
		if ret != config.OK {
			logger.Error("发奖失败 %v %v", zpTaskConfig.RewardId, ret)
		}
		for k, v := range itemOnceMap {
			itemMap[k] += v
		}
	}
	return true, itemMap
}

func ExpireZpActivity(user *sharemem.User) {
	for _, zp := range user.GetZpMap() {

		zpActivityConfig := gdconf.GetZpActivityConfig(zp.ActivityId)
		if zpActivityConfig == nil {
			continue
		}
		if !zpActivityConfig.IsExpire(sharemem.MyShm.TimeNow) {
			continue
		}
		// 转盘保底奖励未领取补发邮件
		for i := 0; i < len(zp.ZpBdRewardList); i++ {
			zpBdReward := &(zp.ZpBdRewardList[i])
			if !zpBdReward.IsUse() {
				break
			}
			if zpBdReward.Count > zp.ZpBdCount {
				continue
			}
			if zpBdReward.Take {
				continue
			}
			if !user.UserQuest.CheckOpenState(sharemem.OpenFuncTypeActivity) {
				continue
			}
			for _, zpBdRewardConfig := range zpActivityConfig.ZpBdRewardList {
				if zpBdRewardConfig.Count == zpBdReward.Count {
					mailConfig := gdconf.GetMailConfig(zpBdRewardConfig.RewardExpireMailId)
					if mailConfig != nil {
						expireTime := uint32(0)
						if mailConfig.ExpireHour != 0 {
							expireTime = uint32(sharemem.MyShm.TimeNow + int64(mailConfig.ExpireHour*3600))
						}
						itemMap := map[int32]int32{zpBdReward.ItemId: zpBdReward.ItemCount}
						AddUserMail(mailConfig.Title, mailConfig.Content, mailConfig.Sender, expireTime, mailConfig.Importance, itemMap, user)
					}
					break
				}
			}
		}
		user.DelZpActivity(zp.ActivityId)
	}
}

func AcceptZpActivity(user *sharemem.User) {
	for _, zpActivityConfig := range gdconf.GetZpActivityConfigMap() {
		if int32(user.Level) < zpActivityConfig.NeedPlayerLevel {
			continue
		}
		if zpActivityConfig.IsExpire(sharemem.MyShm.TimeNow) {
			continue
		}
		zp := user.GetZpById(zpActivityConfig.ActivityId)
		if zp != nil {
			continue
		}
		user.AddZpActivity(zpActivityConfig)
	}
}

func ExpireSignIn(user *sharemem.User) {
	for _, signIn := range user.GetSignInfoMap() {

		if !signIn.IsUse() {
			continue
		}
		var activityConfig = gdconf.GetActivityConfig(signIn.ActivityId)
		if activityConfig == nil {
			continue
		}
		if !activityConfig.IsExpire(sharemem.MyShm.TimeNow) {
			continue
		}
		user.DelSignActivity(activityConfig.ActivityId)
	}
}

func RefreshZpActivityTask(user *sharemem.User) {
	if user.UserActivity.GetLastZpTaskRefreshTime() == 0 {
		user.UserActivity.SetLastZpTaskRefreshTime(sharemem.MyShm.TimeNow)
		return
	}
	nowOffset := tools.ParseTimeToObj(sharemem.MyShm.TimeNow).Add(-(time.Hour * sharemem.RefreshActivityDailyTaskHourOffset))
	lastOffset := time.Unix(user.UserActivity.GetLastZpTaskRefreshTime(), 0).Add(-(time.Hour * sharemem.RefreshActivityDailyTaskHourOffset))
	if nowOffset.Year() == lastOffset.Year() && nowOffset.YearDay() <= lastOffset.YearDay() {
		return
	}
	user.UserActivity.SetLastZpTaskRefreshTime(sharemem.MyShm.TimeNow)

	logger.Debug("[RefreshZpActivityTask]")
	for _, zp := range user.GetZpMap() {
		zpActivityConfig := gdconf.GetZpActivityConfig(zp.ActivityId)
		if zpActivityConfig == nil {
			continue
		}
		for i := 0; i < len(zp.ZpTaskList); i++ {
			zpTask := &(zp.ZpTaskList[i])
			if !zpTask.IsUse() {
				break
			}
			logger.Debug("[RefreshZpActivityTask] check zpTask: %+v", zpTask)
			zpTaskConfig := zpActivityConfig.GetZpTask(zpTask.TaskId)
			if zpTaskConfig == nil {
				logger.Error("zp task config is nil, TaskId: %v", zpTask.TaskId)
				continue
			}
			if zpTaskConfig.RefreshType != gdconf.ZpTaskRefreshTypeDaily {
				continue
			}
			if user.UserQuest.CheckOpenState(sharemem.OpenFuncTypeActivity) {
				// 转盘任务奖励未领取补发邮件
				if zpTask.State == int8(pb.TaskState_TASK_STATE_FINISH) {
					rewardConfig := gdconf.GetConfigReward(zpTaskConfig.RewardId)
					if rewardConfig != nil {
						mailConfig := gdconf.GetMailConfig(zpTaskConfig.RewardExpireMailId)
						if mailConfig != nil {
							expireTime := uint32(0)
							if mailConfig.ExpireHour != 0 {
								expireTime = uint32(sharemem.MyShm.TimeNow + int64(mailConfig.ExpireHour*3600))
							}
							itemMap := rewardConfig.GetRewards(zpTaskConfig.RewardCount, nil, nil)
							AddUserMail(mailConfig.Title, mailConfig.Content, mailConfig.Sender, expireTime, mailConfig.Importance, itemMap, user)
						}
					}
				}
			}
			zpTask.TaskId = zpTaskConfig.TaskId
			zpTask.State = int8(pb.TaskState_TASK_STATE_UNFINISH)
			zpTask.FinishCount = 0
			zpTask.RewardTakeCount = 0
			logger.Debug("[RefreshZpActivityTask] refresh zpTask: %+v", zpTask)
		}
	}
}

func RefreshActivityDailyTask(user *sharemem.User) {
	nowOffset := tools.ParseTimeToObj(sharemem.MyShm.TimeNow).Add(-(time.Hour * sharemem.RefreshActivityDailyTaskHourOffset))
	lastOffset := time.Unix(user.UserActivity.GetLastDailyTaskRefreshTime(), 0).Add(-(time.Hour * sharemem.RefreshActivityDailyTaskHourOffset))
	if nowOffset.Year() == lastOffset.Year() && nowOffset.YearDay() <= lastOffset.YearDay() {
		return
	}
	user.UserActivity.SetLastDailyTaskRefreshTime(sharemem.MyShm.TimeNow)
	user.ResetDailyTaskData()
	AcceptActivityDailyTask(user)
}

func AcceptActivityDailyTask(user *sharemem.User) {
	for _, activityTaskConfig := range gdconf.GetActivityTaskConfigMap() {
		if activityTaskConfig.Type != gdconf.ActivityTaskTypeDaily {
			continue
		}
		if activityTaskConfig.NeedOpenStateId != 0 {
			if !user.UserQuest.CheckOpenState(activityTaskConfig.NeedOpenStateId) {
				continue
			}
		}
		if user.GetDailyTaskById(activityTaskConfig.TaskId) != nil {
			continue
		}
		user.AddDailyTask(activityTaskConfig.TaskId)
	}
}

func RefreshActivityWeeklyTask(user *sharemem.User) {
	nowOffset := tools.ParseTimeToObj(sharemem.MyShm.TimeNow).Add(-(time.Hour * sharemem.RefreshActivityDailyTaskHourOffset))
	lastOffset := time.Unix(user.UserActivity.GetLastWeeklyTaskRefreshTime(), 0).Add(-(time.Hour * sharemem.RefreshActivityDailyTaskHourOffset))
	nowOffsetYear, nowOffsetWeek := nowOffset.ISOWeek()
	lastOffsetYear, lastOffsetWeek := lastOffset.ISOWeek()
	if nowOffsetYear == lastOffsetYear && nowOffsetWeek <= lastOffsetWeek {
		return
	}
	user.UserActivity.SetLastWeeklyTaskRefreshTime(sharemem.MyShm.TimeNow)
	user.ResetWeeklyTaskData()
	AcceptActivityWeeklyTask(user)
}

func AcceptActivityWeeklyTask(user *sharemem.User) {
	for _, activityTaskConfig := range gdconf.GetActivityTaskConfigMap() {
		if activityTaskConfig.Type != gdconf.ActivityTaskTypeWeekly {
			continue
		}
		if activityTaskConfig.NeedOpenStateId != 0 {
			if !user.UserQuest.CheckOpenState(activityTaskConfig.NeedOpenStateId) {
				continue
			}
		}
		if user.GetWeeklyTaskById(activityTaskConfig.TaskId) != nil {
			continue
		}
		user.AddWeeklyTask(activityTaskConfig.TaskId)
	}
}

func RefreshDailyActivitySignIn(user *sharemem.User) {
	nowOffset := tools.ParseTimeToObj(sharemem.MyShm.TimeNow).Add(-(time.Hour * sharemem.RefreshActivitySignInHourOffset))
	lastOffset := time.Unix(user.UserActivity.GetLastDailySignInRefreshTime(), 0).Add(-(time.Hour * sharemem.RefreshActivitySignInHourOffset))
	if nowOffset.Year() == lastOffset.Year() && nowOffset.YearDay() <= lastOffset.YearDay() {
		return
	}
	for _, signIn := range user.GetSignInfoMap() {
		signIn.SignInCount++
		signIn.SignInDailyRoutineRewardTake = false
		user.UserActivity.SetLastDailySignInRefreshTime(sharemem.MyShm.TimeNow)
	}
}

func RefreshActivitySignIn(user *sharemem.User) {
	nowOffset := tools.ParseTimeToObj(sharemem.MyShm.TimeNow).Add(-(time.Hour * sharemem.RefreshActivitySignInHourOffset))
	lastOffset := time.Unix(user.UserActivity.GetLastSignInRefreshTime(), 0).Add(-(time.Hour * sharemem.RefreshActivitySignInHourOffset))
	if nowOffset.Year() == lastOffset.Year() && nowOffset.Month() <= lastOffset.Month() {
		return
	}
	user.ResetSignInData()
	for _, signInActivityConfig := range gdconf.GetSignInActivityConfigMap() {
		if int32(user.Level) < signInActivityConfig.NeedPlayerLevel {
			continue
		}
		now := sharemem.MyShm.TimeNow
		if signInActivityConfig.StartTime != nil && now < signInActivityConfig.StartTime.Unix() {
			continue
		}
		if signInActivityConfig.EndTime != nil && now > signInActivityConfig.EndTime.Unix() {
			continue
		}
		user.AddSignIn(signInActivityConfig)
		user.UserActivity.SetLastSignInRefreshTime(sharemem.MyShm.TimeNow)
	}
}

// ======协议消息处理====

func ActivityDataReq(user *sharemem.User, buf *mysock.SockBuf) int16 {
	req, ok := ParseMsg(config.CS_ActivityDataReq, new(pb.CS_ActivityDataReq), buf, user).(*pb.CS_ActivityDataReq)
	if !ok {
		return config.PROTO_ERROR
	}
	_ = req

	pbDungeonActivityList := make([]*pb.DungeonActivity, 0)
	for _, dungeonActivityConfig := range gdconf.DungeonActivityConfigMap() {
		if dungeonActivityConfig.NeedOpenStateId != 0 {
			if !user.UserQuest.CheckOpenState(dungeonActivityConfig.NeedOpenStateId) {
				continue
			}
		}
		if dungeonActivityConfig.OpenTimeRange != nil {
			if sharemem.MyShm.TimeNow < dungeonActivityConfig.OpenTimeRange[0].Unix() || sharemem.MyShm.TimeNow > dungeonActivityConfig.OpenTimeRange[1].Unix() {
				continue
			}
		}
		dungeonActivity := user.GetDungeonActivity(dungeonActivityConfig.DungeonActivityId)
		pbDungeonActivity := &pb.DungeonActivity{
			ActivityId:    dungeonActivityConfig.DungeonActivityId,
			BeginTime:     0,
			EndTime:       0,
			PassDungeonId: dungeonActivity.PassDungeonId,
		}
		if dungeonActivityConfig.PlayTimeRange != nil {
			pbDungeonActivity.BeginTime = dungeonActivityConfig.PlayTimeRange[0].Unix()
			pbDungeonActivity.EndTime = dungeonActivityConfig.PlayTimeRange[1].Unix()
		}
		pbDungeonActivityList = append(pbDungeonActivityList, pbDungeonActivity)
	}

	SendMsg(config.SC_ActivityDataRsp, &pb.SC_ActivityDataRsp{
		DungeonActivityList: pbDungeonActivityList,
		DailyTask:           user.PacketPbTaskData(pb.TaskType_TASK_TYPE_DAILY),
		WeeklyTask:          user.PacketPbTaskData(pb.TaskType_TASK_TYPE_WEEKLY),
		TowerArea:           user.UserActivity.TowerArea,
		TowerLevel:          user.UserActivity.TowerLevel,
	}, buf, user)
	return config.OK
}

func DungeonQuickFightReq(user *sharemem.User, buf *mysock.SockBuf) int16 {
	req, ok := ParseMsg(config.CS_DungeonQuickFightReq, new(pb.CS_DungeonQuickFightReq), buf, user).(*pb.CS_DungeonQuickFightReq)
	if !ok {
		return config.PROTO_ERROR
	}

	dungeonConfig := gdconf.GetDungeonConfig(req.DungeonId)
	if dungeonConfig == nil {
		SendMsg(config.SC_DungeonQuickFightRsp, &pb.SC_DungeonQuickFightRsp{RetCode: config.CONFIG_NOT_FOUND}, buf, user)
		return config.OK
	}
	if int32(user.Level) < dungeonConfig.PlayerLevelLimit {
		logger.Error("玩家等级没达到地牢等级限制 %v %v", user.Level, dungeonConfig.PlayerLevelLimit)
		SendMsg(config.SC_DungeonQuickFightRsp, &pb.SC_DungeonQuickFightRsp{RetCode: config.SERVER_ERROR}, buf, user)
		return config.OK
	}
	dungeonActivity := user.GetDungeonActivity(dungeonConfig.ActivityId)
	if dungeonActivity == nil {
		logger.Error("获取地牢活动对象失败 %v", dungeonConfig.ActivityId)
		SendMsg(config.SC_DungeonQuickFightRsp, &pb.SC_DungeonQuickFightRsp{RetCode: config.SERVER_ERROR}, buf, user)
		return config.OK
	}
	if req.DungeonId > dungeonActivity.PassDungeonId {
		logger.Error("地牢未解锁 %v", req.DungeonId)
		SendMsg(config.SC_DungeonQuickFightRsp, &pb.SC_DungeonQuickFightRsp{RetCode: config.SERVER_ERROR}, buf, user)
		return config.OK
	}
	costItemMap := map[int32]int32{dungeonConfig.EnterCostItemId: dungeonConfig.EnterCostItemCount * req.Count}
	ok = CostItems(costItemMap, user)
	if !ok {
		logger.Error("道具不足 %v", costItemMap)
		SendMsg(config.SC_DungeonQuickFightRsp, &pb.SC_DungeonQuickFightRsp{RetCode: config.ITEM_NOT_ENOUGH}, buf, user)
		return config.OK
	}
	battleGroupConfig := gdconf.GetBattleGroupConfig(dungeonConfig.BattleGroupId)
	if battleGroupConfig == nil {
		SendMsg(config.SC_DungeonQuickFightRsp, &pb.SC_DungeonQuickFightRsp{RetCode: config.CONFIG_NOT_FOUND}, buf, user)
		return config.OK
	}
	var pbRsp = new(pb.SC_DungeonQuickFightRsp)
	pbRsp.UserCurExp = user.Exp
	pbRsp.UserCurLevel = int32(user.Level)
	pbRsp.RetCode = config.OK
	pbRsp.ExpList = make([]int32, 0)
	itemMap := make(map[int32]int32)
	for i := 0; i < int(req.Count); i++ {
		var tempItemList = new(pb.ItemList)
		var tempRoleExp int32 = 0
		for _, rewardId := range battleGroupConfig.RewardList {
			ret, itemOnceMap, roleExp := RewardItem(rewardId, user.GetTeam(user.GetActiveTeamId()).GetActiveTeamListAll(), user)
			// TODO:需要把增加的 roleExp 同步给客户端
			if ret != config.OK {
				logger.Error("发奖失败 %v %v", rewardId, ret)
				continue
			}
			for k, v := range itemOnceMap {
				itemMap[k] += v
				tempItemList.ItemList = append(tempItemList.ItemList, &pb.Item{Id: k, Num: v})
				if k == gdconf.ITEM_EXP {
					pbRsp.UserTotalAwardExp += v
				}
			}
			tempRoleExp += roleExp
		}
		pbRsp.ExpList = append(pbRsp.ExpList, tempRoleExp)
		pbRsp.ItemList = append(pbRsp.ItemList, tempItemList)
	}

	user.TriggerActivityTask(gdconf.ActivityTaskFinishCondFinishActivityDungeon, dungeonConfig.ActivityId, req.Count)
	user.TriggerActivityTask(gdconf.ActivityTaskFinishCondAnyDungeon, dungeonConfig.ActivityId, req.Count)

	SendMsg(config.SC_TaskDataUpdateNtf, &pb.SC_TaskDataUpdateNtf{Task: user.PacketPbTaskData(pb.TaskType_TASK_TYPE_DAILY)}, buf, user)
	SendMsg(config.SC_TaskDataUpdateNtf, &pb.SC_TaskDataUpdateNtf{Task: user.PacketPbTaskData(pb.TaskType_TASK_TYPE_WEEKLY)}, buf, user)

	SendMsg(config.SC_DungeonQuickFightRsp, pbRsp, buf, user)

	TriggerQuest(user, sharemem.QUEST_FINISH_COND_TYPE_ACTIVITY_DUNGEON, true, dungeonConfig.ActivityId, dungeonConfig.DungeonId)
	TriggerQuest(user, sharemem.QUEST_FINISH_COND_TYPE_ACTIVITY_DUNGEON_COUNT, true, dungeonConfig.ActivityId, req.Count)
	return config.OK
}

func TaskRewardTakeReq(user *sharemem.User, buf *mysock.SockBuf) int16 {
	req, ok := ParseMsg(config.CS_TaskRewardTakeReq, new(pb.CS_TaskRewardTakeReq), buf, user).(*pb.CS_TaskRewardTakeReq)
	if !ok {
		return config.PROTO_ERROR
	}

	activityTaskConfig := gdconf.GetActivityTaskConfig(req.TaskId)
	if activityTaskConfig == nil {
		SendMsg(config.SC_TaskRewardTakeRsp, &pb.SC_TaskRewardTakeRsp{RetCode: config.CONFIG_NOT_FOUND}, buf, user)
		return config.OK
	}

	if req.Type == pb.TaskType_TASK_TYPE_DAILY {
		task := user.GetDailyTaskById(req.TaskId)
		if task == nil {
			logger.Error("日常任务不存在 %v", req.TaskId)
			SendMsg(config.SC_TaskRewardTakeRsp, &pb.SC_TaskRewardTakeRsp{RetCode: config.OBJECT_NOT_FOUND}, buf, user)
			return config.OK
		}

		if pb.TaskState(task.State) != pb.TaskState_TASK_STATE_FINISH {
			logger.Error("日常任务状态不是已完成 %v", task.State)
			SendMsg(config.SC_TaskRewardTakeRsp, &pb.SC_TaskRewardTakeRsp{RetCode: config.SERVER_ERROR}, buf, user)
			return config.OK
		}

		task.State = int8(pb.TaskState_TASK_STATE_ALREADY_REWARD)

		taskPointRewardConfig := ParseTaskPointRewardConfig(gdconf.GetConstStr("DAYACTIVITIONREWARD"))
		if taskPointRewardConfig == nil || len(taskPointRewardConfig) == 0 {
			logger.Error("日常任务活跃点配置解析失败")
			SendMsg(config.SC_TaskRewardTakeRsp, &pb.SC_TaskRewardTakeRsp{RetCode: config.CONFIG_NOT_FOUND}, buf, user)
			return config.OK
		}
		maxDailyTaskPoint := uint32(taskPointRewardConfig[len(taskPointRewardConfig)-1].Point)

		var oldPoint = user.UserActivity.DailyTaskPoint
		user.UserActivity.DailyTaskPoint += uint32(activityTaskConfig.RewardTaskPoint)
		if oldPoint < maxDailyTaskPoint && user.UserActivity.DailyTaskPoint >= maxDailyTaskPoint {
			user.TriggerActivityTask(gdconf.ActivityTaskFinishCondDailyTaskPoint)
		}

		if user.UserActivity.DailyTaskPoint > maxDailyTaskPoint {
			user.UserActivity.DailyTaskPoint = maxDailyTaskPoint
		}
	} else {
		task := user.GetWeeklyTaskById(req.TaskId)
		if task == nil {
			logger.Error("周常任务不存在 %v", req.TaskId)
			SendMsg(config.SC_TaskRewardTakeRsp, &pb.SC_TaskRewardTakeRsp{RetCode: config.OBJECT_NOT_FOUND}, buf, user)
			return config.OK
		}

		if pb.TaskState(task.State) != pb.TaskState_TASK_STATE_FINISH {
			logger.Error("周常任务状态不是已完成 %v", task.State)
			SendMsg(config.SC_TaskRewardTakeRsp, &pb.SC_TaskRewardTakeRsp{RetCode: config.SERVER_ERROR}, buf, user)
			return config.OK
		}

		task.State = int8(pb.TaskState_TASK_STATE_ALREADY_REWARD)

		taskPointRewardConfig := ParseTaskPointRewardConfig(gdconf.GetConstStr("WEEKACTIVITIONREWARD"))
		if taskPointRewardConfig == nil || len(taskPointRewardConfig) == 0 {
			logger.Error("周常任务活跃点配置解析失败")
			SendMsg(config.SC_TaskRewardTakeRsp, &pb.SC_TaskRewardTakeRsp{RetCode: config.CONFIG_NOT_FOUND}, buf, user)
			return config.OK
		}
		maxWeeklyTaskPoint := uint32(taskPointRewardConfig[len(taskPointRewardConfig)-1].Point)

		user.UserActivity.WeeklyTaskPoint += uint32(activityTaskConfig.RewardTaskPoint)
		if user.UserActivity.WeeklyTaskPoint > maxWeeklyTaskPoint {
			user.UserActivity.WeeklyTaskPoint = maxWeeklyTaskPoint
		}
	}
	var itemMap = make(map[int32]int32)
	var itemList = make([]*pb.Item, 0)
	for _, item := range activityTaskConfig.ItemReward {
		itemMap[item.ItemId] += item.ItemCount
		itemList = append(itemList, &pb.Item{Id: item.ItemId, Num: item.ItemCount})
	}
	var ret = AddItems(itemMap, user)
	if ret != config.OK {
		logger.Error("添加道具失败 %v", ret)
	}
	SendMsg(config.SC_TaskDataUpdateNtf, &pb.SC_TaskDataUpdateNtf{Task: user.PacketPbTaskData(pb.TaskType_TASK_TYPE_DAILY)}, buf, user)
	SendMsg(config.SC_TaskDataUpdateNtf, &pb.SC_TaskDataUpdateNtf{Task: user.PacketPbTaskData(pb.TaskType_TASK_TYPE_WEEKLY)}, buf, user)
	SendMsg(config.SC_TaskRewardTakeRsp, &pb.SC_TaskRewardTakeRsp{RetCode: config.OK, ItemList: itemList}, buf, user)
	return config.OK
}

func TaskPointRewardTakeReq(user *sharemem.User, buf *mysock.SockBuf) int16 {
	req, ok := ParseMsg(config.CS_TaskPointRewardTakeReq, new(pb.CS_TaskPointRewardTakeReq), buf, user).(*pb.CS_TaskPointRewardTakeReq)
	if !ok {
		return config.PROTO_ERROR
	}

	pbItemList := make([]*pb.Item, 0)
	if req.Type == pb.TaskType_TASK_TYPE_DAILY {
		taskPointRewardConfig := ParseTaskPointRewardConfig(gdconf.GetConstStr("DAYACTIVITIONREWARD"))
		if taskPointRewardConfig == nil {
			SendMsg(config.SC_TaskPointRewardTakeRsp, &pb.SC_TaskPointRewardTakeRsp{RetCode: config.CONFIG_NOT_FOUND}, buf, user)
			return config.OK
		}
		if req.TaskPointValue > int32(user.UserActivity.DailyTaskPoint) {
			logger.Error("你小子!!! %v %v", req.TaskPointValue, user.UserActivity.WeeklyTaskPoint)
			SendMsg(config.SC_TaskPointRewardTakeRsp, &pb.SC_TaskPointRewardTakeRsp{RetCode: config.SERVER_ERROR}, buf, user)
			return config.OK
		}

		itemMap := make(map[int32]int32)
		for _, taskPointReward := range taskPointRewardConfig {
			if taskPointReward.Point <= int32(user.UserActivity.DailyTaskRewardPointValue) {
				continue
			}
			if taskPointReward.Point > req.TaskPointValue {
				break
			}
			ret, itemMapOnce, _ := RewardItem(taskPointReward.Reward, nil, user)
			if ret != config.OK {
				logger.Error("发奖失败 %v %v", taskPointReward.Reward, ret)
				continue
			}
			for k, v := range itemMapOnce {
				itemMap[k] += v
			}
		}
		for k, v := range itemMap {
			pbItemList = append(pbItemList, &pb.Item{Id: k, Num: v})
		}

		user.UserActivity.DailyTaskRewardPointValue = uint32(req.TaskPointValue)
		SendMsg(config.SC_TaskDataUpdateNtf, &pb.SC_TaskDataUpdateNtf{Task: user.PacketPbTaskData(pb.TaskType_TASK_TYPE_DAILY)}, buf, user)
	} else {
		taskPointRewardConfig := ParseTaskPointRewardConfig(gdconf.GetConstStr("WEEKACTIVITIONREWARD"))
		if taskPointRewardConfig == nil {
			SendMsg(config.SC_TaskPointRewardTakeRsp, &pb.SC_TaskPointRewardTakeRsp{RetCode: config.CONFIG_NOT_FOUND}, buf, user)
			return config.OK
		}
		if req.TaskPointValue > int32(user.UserActivity.WeeklyTaskPoint) {
			logger.Error("你小子!!! %v %v", req.TaskPointValue, user.UserActivity.WeeklyTaskPoint)
			SendMsg(config.SC_TaskPointRewardTakeRsp, &pb.SC_TaskPointRewardTakeRsp{RetCode: config.SERVER_ERROR}, buf, user)
			return config.OK
		}

		itemMap := make(map[int32]int32)
		for _, taskPointReward := range taskPointRewardConfig {
			if taskPointReward.Point <= int32(user.UserActivity.WeeklyTaskRewardPointValue) {
				continue
			}
			if taskPointReward.Point > req.TaskPointValue {
				break
			}
			ret, itemMapOnce, _ := RewardItem(taskPointReward.Reward, nil, user)
			if ret != config.OK {
				logger.Error("发奖失败 %v %v", taskPointReward.Reward, ret)
				continue
			}
			for k, v := range itemMapOnce {
				itemMap[k] += v
			}
		}
		for k, v := range itemMap {
			pbItemList = append(pbItemList, &pb.Item{Id: k, Num: v})
		}

		user.UserActivity.WeeklyTaskRewardPointValue = uint32(req.TaskPointValue)
		SendMsg(config.SC_TaskDataUpdateNtf, &pb.SC_TaskDataUpdateNtf{Task: user.PacketPbTaskData(pb.TaskType_TASK_TYPE_WEEKLY)}, buf, user)
	}

	SendMsg(config.SC_TaskPointRewardTakeRsp, &pb.SC_TaskPointRewardTakeRsp{RetCode: config.OK, ItemList: pbItemList}, buf, user)
	return config.OK
}

func PayActivityInfoReq(user *sharemem.User, buf *mysock.SockBuf) int16 {
	req, ok := ParseMsg(config.CS_PayActivityInfoReq, new(pb.CS_PayActivityInfoReq), buf, user).(*pb.CS_PayActivityInfoReq)
	if !ok {
		return config.PROTO_ERROR
	}
	_ = req

	SendMsg(config.SC_PayActivityInfoRsp, &pb.SC_PayActivityInfoRsp{
		SignInInfoList: user.PacketPbSignInInfoList(),
		ZpInfoList:     user.PacketPbZpInfoList(),
	}, buf, user)
	return config.OK
}

func SignInRewardTakeReq(user *sharemem.User, buf *mysock.SockBuf) int16 {
	req, ok := ParseMsg(config.CS_SignInRewardTakeReq, new(pb.CS_SignInRewardTakeReq), buf, user).(*pb.CS_SignInRewardTakeReq)
	if !ok {
		return config.PROTO_ERROR
	}

	signIn := user.GetSignInfoById(req.ActivityId)
	if signIn == nil {
		SendMsg(config.SC_SignInRewardTakeRsp, &pb.SC_SignInRewardTakeRsp{RetCode: config.OBJECT_NOT_FOUND}, buf, user)
		return config.OK
	}
	if req.RewardDay > signIn.SignInCount {
		logger.Error("你还没签够这么多天呢 %v", req.RewardDay)
		SendMsg(config.SC_SignInRewardTakeRsp, &pb.SC_SignInRewardTakeRsp{RetCode: config.SERVER_ERROR}, buf, user)
		return config.OK
	}
	var retCode = int32(config.OK)
	pbRewardItemList := make([]*pb.Item, 0)
	switch req.Type {
	case pb.SignInRewardTakeType_SIGN_IN_REWARD_TAKE_TYPE_DAILY:
		code, itemMap := signInRewardDaily(user, req)
		if code != config.OK {
			retCode = code
			break
		}
		for k, v := range itemMap {
			pbRewardItemList = append(pbRewardItemList, &pb.Item{Id: k, Num: v})
		}

	case pb.SignInRewardTakeType_SIGN_IN_REWARD_TAKE_TYPE_TOTAL:
		code, itemMap := signInRewardTotal(user, req)
		if code != config.OK {
			retCode = code
			break
		}
		for k, v := range itemMap {
			pbRewardItemList = append(pbRewardItemList, &pb.Item{Id: k, Num: v})
		}
	case pb.SignInRewardTakeType_SIGN_IN_REWARD_TAKE_TYPE_DAILY_ROUTINE:
		code, itemMap := signInRewardDailyRoutine(user, req)
		if code != config.OK {
			retCode = code
			break
		}
		for k, v := range itemMap {
			pbRewardItemList = append(pbRewardItemList, &pb.Item{Id: k, Num: v})
		}
	case pb.SignInRewardTakeType_SIGN_IN_REWARD_TAKE_TYPE_DAILY_AND_DAILY_ROUTINE:
		code, itemMap := signInRewardDaily(user, req)
		for k, v := range itemMap {
			pbRewardItemList = append(pbRewardItemList, &pb.Item{Id: k, Num: v})
		}
		retCode = code
		code, itemMap = signInRewardDailyRoutine(user, req)
		for k, v := range itemMap {
			pbRewardItemList = append(pbRewardItemList, &pb.Item{Id: k, Num: v})
		}
		if len(pbRewardItemList) == 0 {
			retCode = code
		}
	}
	SendMsg(config.SC_SignInRewardTakeRsp, &pb.SC_SignInRewardTakeRsp{RetCode: retCode, RewardItemList: pbRewardItemList, SignInInfoList: user.PacketPbSignInInfoList()}, buf, user)
	return config.OK
}

func ZpReq(user *sharemem.User, buf *mysock.SockBuf) int16 {
	req, ok := ParseMsg(config.CS_ZpReq, new(pb.CS_ZpReq), buf, user).(*pb.CS_ZpReq)
	if !ok {
		return config.PROTO_ERROR
	}

	zp := user.GetZpById(req.ActivityId)
	if zp == nil {
		logger.Error("转盘活动对象不存在 %v", req.ActivityId)
		SendMsg(config.SC_ZpRsp, &pb.SC_ZpRsp{RetCode: config.OBJECT_NOT_FOUND}, buf, user)
		return config.OK
	}
	zpActivityConfig := gdconf.GetZpActivityConfig(zp.ActivityId)
	if zpActivityConfig == nil {
		SendMsg(config.SC_ZpRsp, &pb.SC_ZpRsp{RetCode: config.CONFIG_NOT_FOUND}, buf, user)
		return config.OK
	}
	ok = CostItems(map[int32]int32{zpActivityConfig.OnceCostItem.ItemId: zpActivityConfig.OnceCostItem.ItemCount * req.Count}, user)
	if !ok {
		SendMsg(config.SC_ZpRsp, &pb.SC_ZpRsp{RetCode: config.ITEM_NOT_ENOUGH}, buf, user)
		return config.OK
	}
	pbRewardIndexList := make([]int32, 0)
	pbRewardItemList := make([]*pb.Item, 0)
	addItemMap := make(map[int32]int32)
	for i := 0; i < int(req.Count); i++ {
		zpReward := sharemem.RWSRandom[*gdconf.ZpReward](zpActivityConfig.ZpRewardList)
		if zpReward == nil {
			logger.Error("转盘抽奖随机失败 %v", zpActivityConfig.ZpRewardList)
			continue
		}
		zp.ZpBdCount++
		addItemMap[zpReward.ItemId] += zpReward.ItemCount
		pbRewardIndexList = append(pbRewardIndexList, zpReward.Index)
		pbRewardItemList = append(pbRewardItemList, &pb.Item{Id: zpReward.ItemId, Num: zpReward.ItemCount})
	}
	ret := AddItems(addItemMap, user)
	if ret != config.OK {
		logger.Error("添加道具失败 %v", ret)
	}

	SendMsg(config.SC_ZpRsp, &pb.SC_ZpRsp{
		RetCode:         config.OK,
		RewardIndexList: pbRewardIndexList,
		RewardItemList:  pbRewardItemList,
		ZpInfo:          zp.PacketPbZpInfo(),
	}, buf, user)
	return config.OK
}

func ZpBdRewardTakeReq(user *sharemem.User, buf *mysock.SockBuf) int16 {
	req, ok := ParseMsg(config.CS_ZpBdRewardTakeReq, new(pb.CS_ZpBdRewardTakeReq), buf, user).(*pb.CS_ZpBdRewardTakeReq)
	if !ok {
		return config.PROTO_ERROR
	}

	zp := user.GetZpById(req.ActivityId)
	if zp == nil {
		logger.Error("转盘活动对象不存在 %v", req.ActivityId)
		SendMsg(config.SC_ZpBdRewardTakeRsp, &pb.SC_ZpBdRewardTakeRsp{RetCode: config.OBJECT_NOT_FOUND}, buf, user)
		return config.OK
	}
	if req.Count > zp.ZpBdCount {
		logger.Error("搁着作弊呢??? %v", req.Count)
		SendMsg(config.SC_ZpBdRewardTakeRsp, &pb.SC_ZpBdRewardTakeRsp{RetCode: config.OBJECT_NOT_FOUND}, buf, user)
		return config.OK
	}
	var targetZpBdReward *sharemem.ZpBdReward = nil
	for i := 0; i < len(zp.ZpBdRewardList); i++ {
		zpBdReward := &(zp.ZpBdRewardList[i])
		if !zpBdReward.IsUse() {
			break
		}
		if zpBdReward.Count == req.Count {
			targetZpBdReward = zpBdReward
			break
		}
	}
	if targetZpBdReward == nil {
		logger.Error("转盘活动保底奖励对象不存在 %v", req.Count)
		SendMsg(config.SC_ZpBdRewardTakeRsp, &pb.SC_ZpBdRewardTakeRsp{RetCode: config.OBJECT_NOT_FOUND}, buf, user)
		return config.OK
	}
	if targetZpBdReward.Take {
		logger.Error("转盘活动保底奖励对象已领奖 %v", req.Count)
		SendMsg(config.SC_ZpBdRewardTakeRsp, &pb.SC_ZpBdRewardTakeRsp{RetCode: config.SERVER_ERROR}, buf, user)
		return config.OK
	}
	targetZpBdReward.Take = true
	ret := AddItems(map[int32]int32{targetZpBdReward.ItemId: targetZpBdReward.ItemCount}, user)
	if ret != config.OK {
		logger.Error("添加道具失败 %v", ret)
	}

	SendMsg(config.SC_ZpBdRewardTakeRsp, &pb.SC_ZpBdRewardTakeRsp{
		RetCode:        config.OK,
		RewardItemList: []*pb.Item{{Id: targetZpBdReward.ItemId, Num: targetZpBdReward.ItemCount}},
		ZpInfo:         zp.PacketPbZpInfo(),
	}, buf, user)
	return config.OK
}

func PayActivityTaskRewardTakeReq(user *sharemem.User, buf *mysock.SockBuf) int16 {
	req, ok := ParseMsg(config.CS_PayActivityTaskRewardTakeReq, new(pb.CS_PayActivityTaskRewardTakeReq), buf, user).(*pb.CS_PayActivityTaskRewardTakeReq)
	if !ok {
		return config.PROTO_ERROR
	}

	zp := user.GetZpById(req.ActivityId)
	if zp == nil {
		logger.Error("转盘活动对象不存在 %v", req.ActivityId)
		SendMsg(config.SC_PayActivityTaskRewardTakeRsp, &pb.SC_PayActivityTaskRewardTakeRsp{RetCode: config.OBJECT_NOT_FOUND}, buf, user)
		return config.OK
	}
	zpActivityConfig := gdconf.GetZpActivityConfig(zp.ActivityId)
	if zpActivityConfig == nil {
		SendMsg(config.SC_PayActivityTaskRewardTakeRsp, &pb.SC_PayActivityTaskRewardTakeRsp{RetCode: config.CONFIG_NOT_FOUND}, buf, user)
		return config.OK
	}
	pbItemList := make([]*pb.Item, 0)
	if req.All {
		itemMap := make(map[int32]int32)
		for i := 0; i < len(zp.ZpTaskList); i++ {
			ZpTask := &(zp.ZpTaskList[i])
			if !ZpTask.IsUse() {
				break
			}
			if pb.TaskState(ZpTask.State) != pb.TaskState_TASK_STATE_FINISH {
				continue
			}
			ok, itemOnceMap := zpTaskRewardTake(user, ZpTask, zpActivityConfig)
			if !ok {
				continue
			}
			for k, v := range itemOnceMap {
				itemMap[k] += v
			}
		}
		for k, v := range itemMap {
			pbItemList = append(pbItemList, &pb.Item{Id: k, Num: v})
		}
	} else {
		var targetZpTask *sharemem.Task = nil
		for i := 0; i < len(zp.ZpTaskList); i++ {
			ZpTask := &(zp.ZpTaskList[i])
			if !ZpTask.IsUse() {
				break
			}
			if ZpTask.TaskId == req.TaskId {
				targetZpTask = ZpTask
				break
			}
		}
		if targetZpTask == nil {
			logger.Error("转盘活动任务对象不存在 %v", req.TaskId)
			SendMsg(config.SC_PayActivityTaskRewardTakeRsp, &pb.SC_PayActivityTaskRewardTakeRsp{RetCode: config.OBJECT_NOT_FOUND}, buf, user)
			return config.OK
		}
		ok, itemMap := zpTaskRewardTake(user, targetZpTask, zpActivityConfig)
		if !ok {
			SendMsg(config.SC_PayActivityTaskRewardTakeRsp, &pb.SC_PayActivityTaskRewardTakeRsp{RetCode: config.SERVER_ERROR}, buf, user)
			return config.OK
		}
		for k, v := range itemMap {
			pbItemList = append(pbItemList, &pb.Item{Id: k, Num: v})
		}
	}

	SendMsg(config.SC_PayActivityTaskRewardTakeRsp, &pb.SC_PayActivityTaskRewardTakeRsp{
		RetCode:  config.OK,
		ItemList: pbItemList,
		TaskList: zp.PacketPbZpTask(),
	}, buf, user)
	return config.OK
}
